package com.education.platform.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.education.platform.common.ResultCode;
import com.education.platform.dto.feedback.FeedbackCreateDTO;
import com.education.platform.dto.feedback.FeedbackReplyDTO;
import com.education.platform.entity.Feedback;
import com.education.platform.exception.BusinessException;
import com.education.platform.mapper.FeedbackMapper;
import com.education.platform.service.FeedbackService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 反馈服务实现类
 *
 * @author education-platform
 * @since 2024-09-27
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class FeedbackServiceImpl implements FeedbackService {

    private final FeedbackMapper feedbackMapper;

    @Override
    @Transactional
    public Long createFeedback(FeedbackCreateDTO feedbackCreateDTO) {
        Feedback feedback = new Feedback();
        BeanUtil.copyProperties(feedbackCreateDTO, feedback);
        
        // 设置用户ID
        Long userId = StpUtil.getLoginIdAsLong();
        feedback.setUserId(userId);
        
        // 处理图片列表
        if (feedbackCreateDTO.getImages() != null && !feedbackCreateDTO.getImages().isEmpty()) {
            feedback.setImages(JSONUtil.toJsonStr(feedbackCreateDTO.getImages()));
        }
        
        // 设置默认状态
        feedback.setStatus(Feedback.Status.PENDING.name());
        
        // 设置默认优先级
        if (feedback.getPriority() == null) {
            feedback.setPriority(Feedback.Priority.NORMAL.name());
        }
        
        feedbackMapper.insert(feedback);
        log.info("创建反馈成功, ID: {}, 用户: {}", feedback.getId(), userId);
        return feedback.getId();
    }

    @Override
    @Transactional
    public void updateFeedback(Long id, FeedbackCreateDTO feedbackCreateDTO) {
        Feedback feedback = getFeedbackById(id);
        
        // 检查权限：只有反馈提交者本人可以修改
        Long userId = StpUtil.getLoginIdAsLong();
        if (!feedback.getUserId().equals(userId)) {
            throw new BusinessException(ResultCode.FORBIDDEN);
        }
        
        // 只有待处理状态的反馈可以修改
        if (!Feedback.Status.PENDING.name().equals(feedback.getStatus())) {
            throw new BusinessException(ResultCode.SYSTEM_ERROR);
        }
        
        BeanUtil.copyProperties(feedbackCreateDTO, feedback, "id", "userId", "status", "reply", "repliedBy", "repliedAt", "createdAt");
        
        // 处理图片列表
        if (feedbackCreateDTO.getImages() != null && !feedbackCreateDTO.getImages().isEmpty()) {
            feedback.setImages(JSONUtil.toJsonStr(feedbackCreateDTO.getImages()));
        }
        
        feedbackMapper.updateById(feedback);
        log.info("更新反馈成功, ID: {}", id);
    }

    @Override
    @Transactional
    public void deleteFeedback(Long id) {
        Feedback feedback = getFeedbackById(id);
        
        // 检查权限：只有反馈提交者本人或管理员可以删除
        Long userId = StpUtil.getLoginIdAsLong();
        if (!feedback.getUserId().equals(userId) && !StpUtil.hasRole("ADMIN")) {
            throw new BusinessException(ResultCode.FORBIDDEN);
        }
        
        feedbackMapper.deleteById(id);
        log.info("删除反馈成功, ID: {}", id);
    }

    @Override
    public Feedback getFeedbackById(Long id) {
        Feedback feedback = feedbackMapper.selectById(id);
        if (feedback == null) {
            throw new BusinessException(ResultCode.NOT_FOUND);
        }
        return feedback;
    }

    @Override
    public IPage<Feedback> getFeedbackPage(Page<Feedback> page, String type, String status, String priority) {
        return feedbackMapper.selectFeedbackPageWithUser(page, type, status, priority);
    }

    @Override
    public IPage<Feedback> getFeedbackPageWithKeyword(Page<Feedback> page, String type, String status, String priority, String keyword) {
        return feedbackMapper.selectFeedbackPageWithKeyword(page, type, status, priority, keyword);
    }

    @Override
    public List<Feedback> getMyFeedbacks(Long userId) {
        return feedbackMapper.selectByUserId(userId);
    }

    @Override
    @Transactional
    public void replyFeedback(Long id, FeedbackReplyDTO feedbackReplyDTO) {

        Feedback feedback = getFeedbackById(id);
        
        Long adminId = StpUtil.getLoginIdAsLong();
        feedback.setReply(feedbackReplyDTO.getReply());
        feedback.setRepliedBy(adminId);
        feedback.setRepliedAt(LocalDateTime.now());
        // 根据DTO中的status设置状态，如果没有则默认为PROCESSING
        if (feedbackReplyDTO.getStatus() != null && !feedbackReplyDTO.getStatus().isEmpty()) {
            feedback.setStatus(feedbackReplyDTO.getStatus());
        } else {
            feedback.setStatus(Feedback.Status.PROCESSING.name());
        }
        
        feedbackMapper.updateById(feedback);
        log.info("回复反馈成功, ID: {}, 管理员: {}", id, adminId);
    }

    @Override
    @Transactional
    public void updateStatus(Long id, String status) {
        // 只有管理员可以更新状态
        if (!StpUtil.hasRole("ADMIN")) {
            throw new BusinessException(ResultCode.FORBIDDEN);
        }
        
        Feedback feedback = getFeedbackById(id);
        feedback.setStatus(status);
        feedbackMapper.updateById(feedback);
        log.info("更新反馈状态成功, ID: {}, 状态: {}", id, status);
    }

    @Override
    public List<Feedback> getPendingFeedbacks() {
        return feedbackMapper.selectPendingFeedbacks();
    }

    @Override
    public List<Feedback> getHighPriorityFeedbacks() {
        return feedbackMapper.selectHighPriorityFeedbacks();
    }

    @Override
    @Transactional
    public void closeFeedback(Long id) {
        // 只有管理员可以关闭
        if (!StpUtil.hasRole("ADMIN")) {
            throw new BusinessException(ResultCode.FORBIDDEN);
        }
        
        Feedback feedback = getFeedbackById(id);
        feedback.setStatus(Feedback.Status.CLOSED.name());
        feedbackMapper.updateById(feedback);
        log.info("关闭反馈成功, ID: {}", id);
    }
}

